package org.example.controller;

import com.bianmaba.commons.annotation.WrapResult;
import com.bianmaba.commons.bean.exceptions.OperationException;
import org.example.bean.entity.User;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.core.MethodParameter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.util.ReflectionUtils;
import org.springframework.validation.BindException;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
import org.springframework.web.multipart.support.MissingServletRequestPartException;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * @program: example-spring-boot-extend
 * @description:
 * @author: Chenjiabin
 * @create: 2019/4/23 14:37
 **/
public class ExceptionControllerSupport {
    @RequestMapping("operationException")
    @WrapResult
    public Object operationException() {
        throw new OperationException("OperationException", 50001);
    }

    @WrapResult
    @RequestMapping("runtimeException")
    public Object runtimeException() {
        throw new RuntimeException("RuntimeException");
    }

    @WrapResult
    @RequestMapping("exception")
    public Object exception() throws Exception {
        throw new Exception("Exception");
    }

    @WrapResult
    @RequestMapping("httpRequestMethodNotSupportedException")
    public Object httpRequestMethodNotSupportedException() throws HttpRequestMethodNotSupportedException {
        throw new HttpRequestMethodNotSupportedException("HttpRequestMethodNotSupportedException");
    }

    @WrapResult
    @RequestMapping("httpMediaTypeNotSupportedException")
    public Object httpMediaTypeNotSupportedException() throws HttpMediaTypeNotSupportedException {
        throw new HttpMediaTypeNotSupportedException("HttpMediaTypeNotSupportedException");
    }

    @WrapResult
    @RequestMapping("httpMediaTypeNotAcceptableException")
    public Object httpMediaTypeNotAcceptableException() throws HttpMediaTypeNotAcceptableException {
        throw new HttpMediaTypeNotAcceptableException("HttpMediaTypeNotAcceptableException");
    }

    @WrapResult
    @RequestMapping("missingPathVariableException")
    public Object missingPathVariableException() throws MissingPathVariableException {
        throw new MissingPathVariableException("MissingPathVariableException", null);
    }

    @WrapResult
    @RequestMapping("missingServletRequestParameterException")
    public Object missingServletRequestParameterException() throws MissingServletRequestParameterException {

        throw new MissingServletRequestParameterException("MissingServletRequestParameterException", null);
    }

    @WrapResult
    @RequestMapping("servletRequestBindingException")
    public Object servletRequestBindingException() throws ServletRequestBindingException {
        throw new ServletRequestBindingException("ServletRequestBindingException", null);
    }

    @WrapResult
    @RequestMapping("conversionNotSupportedException")
    public Object conversionNotSupportedException() throws ConversionNotSupportedException {
        throw new ConversionNotSupportedException("ConversionNotSupportedException", String.class, null);
    }

    @WrapResult

    @RequestMapping("typeMismatchException")
    public Object typeMismatchException() throws TypeMismatchException {
        throw new TypeMismatchException("TypeMismatchException", String.class, null);
    }

    @WrapResult
    @RequestMapping("httpMessageNotReadableException")
    public Object httpMessageNotReadableException(HttpServletRequest request) throws HttpMessageNotReadableException {
        throw new HttpMessageNotReadableException("HttpMessageNotReadableException", new ServletServerHttpRequest(request));
    }

    @WrapResult
    @RequestMapping("httpMessageNotWritableException")
    public Object httpMessageNotWritableException() throws HttpMessageNotWritableException {
        throw new HttpMessageNotWritableException("HttpMessageNotWritableException");
    }

    @WrapResult
    @RequestMapping("methodArgumentNotValidException")
    public Object methodArgumentNotValidException() throws MethodArgumentNotValidException {
        Method method = ReflectionUtils.findMethod(this.getClass(), "methodArgumentNotValidException");
        throw new MethodArgumentNotValidException(new MethodParameter(method, 0), null);
    }

    @WrapResult
    @RequestMapping("bindException")
    public Object bindException() throws BindException {
        throw new BindException(null, null);
    }

    @WrapResult
    @RequestMapping("missingServletRequestPartException")
    public Object missingServletRequestPartException() throws MissingServletRequestPartException {
        throw new MissingServletRequestPartException("MissingServletRequestPartException");
    }

    @WrapResult
    @RequestMapping("noHandlerFoundException")
    public Object noHandlerFoundException(HttpServletRequest request) throws NoHandlerFoundException {
        throw new NoHandlerFoundException("NoHandlerFoundException", request.getRequestURI(), null);
    }

    @WrapResult
    @RequestMapping("asyncRequestTimeoutException")
    public Object asyncRequestTimeoutException() throws AsyncRequestTimeoutException {
        throw new AsyncRequestTimeoutException();
    }


    @WrapResult
    @RequestMapping("argumentException")
    public Object argumentException() throws IllegalArgumentException {
        throw new IllegalArgumentException("IllegalArgumentException");
    }


    @WrapResult
    @RequestMapping("badRequest")
    public Object badRequest(@RequestBody() User user) {
        return user;
    }
}
